# -*- coding: UTF-8 -*-
import ssl
import socket
import smtplib
import whois
import logging
from cryptography import x509
from cryptography.hazmat.backends import default_backend
from datetime import datetime
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText


domain_ssl_list = [
    "wenwohealth.com",
    "box.wenwohealth.com",
    "wiki.dev.wenwo.com",
    "wenwo-img.wenwo.com",
    "www-dev.wenwo.com",
    "www-test.wenwo.com",
    "www-rebuild-test.wenwo.com",
    "www-uat.wenwo.com",
    "admin-dev.wenwo.com",
    "admin-rebuild-test.wenwo.com",
    "admin-test.wenwo.com",
    "admin-uat.wenwo.com",
    "www.wenwo.com",
    "doctor.wenwo.com",
    "pic.wenwo.com",
    "wenwo.com",
    "dev.wenwo.com",
    "api.wenwo.com",
    "col.live.v.wenwo.com",
    "pic.991kang.com",
    "www-dev.991kang.com",
    "www-rebuild-test.991kang.com",
    "www-test.991kang.com",
    "www.991kang.com",
    "www-uat.991kang.com",
    "b.health.sina.cn",
    "health.sina.cn",
]

domain_data_list = [
    "iwask.com",
    "wenwohealth.com",
    "aw-ehos.com",
    "junttech.com",
    "aiyihos.com",
    "sina.cn",
    "jiujiuyikang.com",
    "991kang.com",
    "pingcl.com",
    "wenwo.com",
]


# 设置日志
log_file_path = "/data/python/log/ssl_domain.log"  # 指定日志文件路径
logging.basicConfig(
    filename=log_file_path,
    level=logging.INFO,
    format="%(asctime)s - %(levelname)s - %(message)s",
    datefmt="%Y-%m-%d %H:%M:%S",
)


def connect_to_server():
    smtp_server = "smtp.mxhichina.com"
    port = 80
    sender_email = "noreply@pingcl.com"
    password = "p2q7hDokTA%BpmG"
    try:
        server = smtplib.SMTP(smtp_server, port)
        server.ehlo()
        server.starttls()
        server.ehlo()
        server.login(sender_email, password)
        logging.info("邮件服务器连接成功。")
        return server
    except Exception as e:
        logging.error("无法连接邮件服务器：" + str(e))
        raise


def Send_Mail(messages):
    # 获取当前日期和时间
    now = datetime.now()
    server = connect_to_server()

    sender_email = "noreply@pingcl.com"
    receiver_email = ["runfa.li@pingcl.com", "taoming.zhou@pingcl.com"]

    subject = f"告警-域名与SSL证书({now})"
    # 将messages中的文本加粗，整个消息使用HTML格式
    message = messages

    email = MIMEMultipart()
    email["From"] = sender_email
    email["To"] = ", ".join(receiver_email)
    email["Subject"] = subject
    # 将邮件正文格式设置为HTML
    email.attach(MIMEText(message, "html"))

    try:
        server.send_message(email)
        server.quit()
        logging.info("邮件发送成功！")
    except Exception as e:
        logging.error("邮件发送失败：" + str(e))


def get_ssl_expiry_date(hostname, port=443):
    context = ssl.create_default_context()
    context.check_hostname = False
    context.verify_mode = ssl.CERT_NONE

    try:
        with socket.create_connection((hostname, port)) as sock:
            with context.wrap_socket(sock, server_hostname=hostname) as ssock:
                der_cert = ssock.getpeercert(True)  # 获取DER格式的证书
                # 将二进制DER格式证书转换为x509.Certificate对象
                cert = x509.load_der_x509_certificate(der_cert, default_backend())
                # 获取证书的过期时间
                expiry_date = cert.not_valid_after
                logging.info(f"获取到域名 {hostname} SSL证书 过期时间。")
                return expiry_date
    except Exception as e:
        logging.error(f"无法获取到域名 {hostname} SSL证书 过期时间：" + str(e))
        raise


def get_domain_data(domain):
    # 查询域名的 Whois 记录
    w = whois.whois(domain)
    try:
        # 获取域名的到期日期
        if isinstance(w.expiration_date, list):
            expiry_date = w.expiration_date[0]
        else:
            expiry_date = w.expiration_date
        logging.info(f"获取到域名 {domain} 过期时间。")
        return expiry_date
    except Exception as e:
        logging.error(f"无法获取到域名 {domain} 过期时间：" + str(e))
        raise


def send_ssl_mail():
    expiry_info = {}  # 用于跟踪每个域名的最短剩余天数
    logging.info("正在检查 SSL证书 到期日期...")
    for hostname in domain_ssl_list:
        d30 = 30
        d15 = 15
        d60 = 60
        expiry_date = get_ssl_expiry_date(hostname)
        today = datetime.now()
        remaining_days = (expiry_date - today).days  # 计算剩余天数

        # 更新expiry_info字典，存储剩余天数和过期日期
        if hostname not in expiry_info or remaining_days < expiry_info[hostname][0]:
            expiry_info[hostname] = (remaining_days, expiry_date)

    # 构建最终的消息列表
    final_messages = []
    for hostname, (days, expiry_date) in expiry_info.items():
        if days <= d60:
            if days <= d15:
                message = f"<strong>{hostname} 过期时间为 {expiry_date.strftime('%Y-%m-%d')}，还有 {days} 天过期。<br></strong>"
            elif days <= d30:
                message = f"<strong>{hostname} 过期时间为 {expiry_date.strftime('%Y-%m-%d')}，还有 {days} 天过期。<br></strong>"
            else:
                message = f"<strong>{hostname} 过期时间为 {expiry_date.strftime('%Y-%m-%d')}，还有 {days} 天过期。<br></strong>"
            final_messages.append(message)

    # 将所有消息合并为一个字符串
    final_message = "".join(final_messages)
    if not final_messages:  # 检查final_messages列表是否为空
        print("没有即将到期的SSL证书。")
        logging.info("没有即将到期的SSL证书。")
    else:
        messages = "您好！<br>以下SSL证书即将到期：<br>" + final_message + "请关注！"
        print(messages)
        Send_Mail(messages)


def send_domain_mail():
    expiry_info = {}  # 用于跟踪每个域名的最短剩余天数
    logging.info("正在检查 域名 到期日期...")
    for domain in domain_data_list:
        d30 = 30
        d15 = 15
        d60 = 60
        expiry_date = get_domain_data(domain)
        today = datetime.now()
        remaining_days = (expiry_date - today).days  # 计算剩余天数

        # 更新expiry_info字典，存储剩余天数和过期日期
        if domain not in expiry_info or remaining_days < expiry_info[domain][0]:
            expiry_info[domain] = (remaining_days, expiry_date)

    # 构建最终的消息列表
    final_messages = []
    for domain, (days, expiry_date) in expiry_info.items():
        if days <= d60:
            if days <= d15:
                message = f"<strong>{domain} 过期时间为 {expiry_date.strftime('%Y-%m-%d')}，还有 {days} 天过期。<br></strong>"
            elif days <= d30:
                message = f"<strong>{domain} 过期时间为 {expiry_date.strftime('%Y-%m-%d')}，还有 {days} 天过期。<br></strong>"
            else:
                message = f"<strong>{domain} 过期时间为 {expiry_date.strftime('%Y-%m-%d')}，还有 {days} 天过期。<br></strong>"
            final_messages.append(message)

    # 将所有消息合并为一个字符串
    final_message = "".join(final_messages)
    if not final_messages:  # 检查final_messages列表是否为空
        print("没有即将到期的域名。")
        logging.info("没有即将到期的域名。")
    else:
        messages = "您好！<br>以下域名即将到期：<br>" + final_message + "请关注！"
        print(messages)
        Send_Mail(messages)


if __name__ == "__main__":
    logging.info("程序开始运行...")
    send_ssl_mail()
    send_domain_mail()
    logging.info("程序运行结束...\n")
